/**
 * JZ UnoCSS - 处理器模块
 * 处理代码、生成CSS、写入文件等核心功能
 * @version 1.1.0
 * @author jz
 */

import { generateCSS } from '../core/generator.js';
import { utils } from '../utils/utils.js';

/**
 * 处理代码中的类名
 * @param {string} code - 源代码
 * @param {Object} options - 处理选项
 * @param {string} filePath - 文件路径（可选）
 * @returns {string} 处理后的代码
 */
export function processCode(code, options = {}, filePath = '') {
    // 目前直接返回原代码，不进行任何转换
    // 因为我们的CSS是通过外部文件引入的，不需要修改源代码
    return code;
}

/**
 * 安全提取动态类名中的字符串字面量
 * 支持Vue的各种动态类名语法
 * @param {string} expression - 动态类名表达式
 * @returns {string[]} 提取到的类名数组
 */
function extractClassNamesFromDynamicExpression(expression) {
    const classNames = new Set();
    
    try {
        // 预处理：去除表达式中的HTML实体编码
        const cleanExpression = expression.replace(/&quot;/g, '"').replace(/&#39;/g, "'");
        
        // 只在开发模式下输出详细日志
        const isDev = globalThis.process?.env?.NODE_ENV !== 'production';
        if (isDev) {
            console.log(`[JZ UnoCSS] 处理表达式: "${cleanExpression}"`);
        }
        
        // 1. 提取所有单引号字符串字面量（使用更精确的正则）
        const singleQuoteMatches = cleanExpression.match(/'([^'\\]*(\\.[^'\\]*)*)'/g);
        if (singleQuoteMatches) {
            if (isDev) console.log(`[JZ UnoCSS] 找到单引号字符串:`, singleQuoteMatches);
            singleQuoteMatches.forEach(match => {
                const className = match.slice(1, -1); // 移除引号
                if (className && className.trim()) {
                    if (className.includes(' ')) {
                        // 处理包含多个类名的字符串，如 'class1 class2'
                        className.split(/\s+/).forEach(cls => {
                            if (cls.trim()) {
                                classNames.add(cls.trim());
                            }
                        });
                    } else {
                        classNames.add(className.trim());
                    }
                }
            });
        }
        
        // 2. 提取所有双引号字符串字面量（处理嵌套情况）
        const doubleQuoteMatches = cleanExpression.match(/"([^"\\]*(\\.[^"\\]*)*)"/g);
        if (doubleQuoteMatches) {
            if (isDev) console.log(`[JZ UnoCSS] 找到双引号字符串:`, doubleQuoteMatches);
            doubleQuoteMatches.forEach(match => {
                const className = match.slice(1, -1); // 移除引号
                if (className && className.trim()) {
                    if (className.includes(' ')) {
                        // 处理包含多个类名的字符串
                        className.split(/\s+/).forEach(cls => {
                            if (cls.trim()) {
                                classNames.add(cls.trim());
                            }
                        });
                    } else {
                        classNames.add(className.trim());
                    }
                }
            });
        }
        
        // 3. 额外处理：使用更简单的方式查找所有可能的CSS类名模式
        // 匹配看起来像CSS类名的字符串（包含 - 的标识符）
        const cssClassPattern = /['"]([a-zA-Z][a-zA-Z0-9_-]*(?:\s+[a-zA-Z][a-zA-Z0-9_-]*)*)['"]/g;
        let cssMatch;
        while ((cssMatch = cssClassPattern.exec(cleanExpression)) !== null) {
            const classString = cssMatch[1];
            if (classString && classString.trim()) {
                if (classString.includes(' ')) {
                    classString.split(/\s+/).forEach(cls => {
                        if (cls.trim()) {
                            classNames.add(cls.trim());
                        }
                    });
                } else {
                    classNames.add(classString.trim());
                }
            }
        }
        
        // 3.1 专门处理三元表达式中的字符串
        // 特别针对: condition ? 'class1 class2' : 'class3 class4' 这种模式
        const ternaryPattern = /\?\s*['"]([^'"]+)['"]\s*:\s*['"]([^'"]+)['"]/g;
        let ternaryMatch;
        while ((ternaryMatch = ternaryPattern.exec(cleanExpression)) !== null) {
            // 处理 ? 后面的类名
            const trueClasses = ternaryMatch[1];
            if (trueClasses && trueClasses.trim()) {
                if (trueClasses.includes(' ')) {
                    trueClasses.split(/\s+/).forEach(cls => {
                        if (cls.trim()) {
                            classNames.add(cls.trim());
                        }
                    });
                } else {
                    classNames.add(trueClasses.trim());
                }
            }
            
            // 处理 : 后面的类名
            const falseClasses = ternaryMatch[2];
            if (falseClasses && falseClasses.trim()) {
                if (falseClasses.includes(' ')) {
                    falseClasses.split(/\s+/).forEach(cls => {
                        if (cls.trim()) {
                            classNames.add(cls.trim());
                        }
                    });
                } else {
                    classNames.add(falseClasses.trim());
                }
            }
        }
        
        // 4. 提取对象键名中的类名（用于 { 'class-name': condition } 语法）
        const objectKeyMatches = cleanExpression.match(/['"]([^'"]+)['"]:\s*[\w.!?&|]+/g);
        if (objectKeyMatches) {
            objectKeyMatches.forEach(match => {
                const keyMatch = match.match(/['"]([^'"]+)['"]/);
                if (keyMatch && keyMatch[1]) {
                    const className = keyMatch[1].trim();
                    if (className) {
                        classNames.add(className);
                    }
                }
            });
        }
        
        // 5. 处理不带引号的对象键名（用于 { className: condition } 语法）
        const unquotedKeyMatches = cleanExpression.match(/\{\s*([a-zA-Z_$][a-zA-Z0-9_$-]*)\s*:/g);
        if (unquotedKeyMatches) {
            unquotedKeyMatches.forEach(match => {
                const keyMatch = match.match(/\{\s*([a-zA-Z_$][a-zA-Z0-9_$-]*)\s*:/);
                if (keyMatch && keyMatch[1]) {
                    const className = keyMatch[1].trim();
                    // 只处理看起来像CSS类名的标识符
                    if (className && /^[a-zA-Z][a-zA-Z0-9_-]*$/.test(className)) {
                        classNames.add(className);
                    }
                }
            });
        }
        
        // 6. 处理数组语法中的字符串字面量 [ˋclass1ˋ, ˋclass2ˋ]
        const arrayStringMatches = cleanExpression.match(/\[([^\]]*)\]/g);
        if (arrayStringMatches) {
            arrayStringMatches.forEach(arrayMatch => {
                const arrayContent = arrayMatch.slice(1, -1); // 移除 [ ]
                // 从数组内容中提取字符串字面量
                const stringInArray = arrayContent.match(/['"]([^'"]+)['"]/g);
                if (stringInArray) {
                    stringInArray.forEach(str => {
                        const className = str.slice(1, -1);
                        if (className && className.trim()) {
                            if (className.includes(' ')) {
                                className.split(/\s+/).forEach(cls => {
                                    if (cls.trim()) {
                                        classNames.add(cls.trim());
                                    }
                                });
                            } else {
                                classNames.add(className.trim());
                            }
                        }
                    });
                }
            });
        }
        
        // 7. 处理模板字符串中的 text-ellipsis 类名模式
        // 匹配 `text-ellipsis-${num}` 或 `text-ellipsis-${variable}` 等模式
        const templateStringMatches = cleanExpression.match(/`([^`]*text-ellipsis-\$\{[^}]+\}[^`]*)`/g);
        if (templateStringMatches) {
            if (isDev) console.log(`[JZ UnoCSS] 找到模板字符串:`, templateStringMatches);
            templateStringMatches.forEach(template => {
                const templateContent = template.slice(1, -1); // 移除反引号
                // 检查是否是 text-ellipsis 模式
                if (templateContent.includes('text-ellipsis-${')) {
                    // 为 1-10 生成所有可能的 text-ellipsis 类名
                    for (let i = 1; i <= 10; i++) {
                        classNames.add(`text-ellipsis-${i}`);
                    }
                    if (isDev) console.log(`[JZ UnoCSS] 从模板字符串生成 text-ellipsis-1 到 text-ellipsis-10`);
                }
            });
        }
        
        // 8. 处理函数调用中的 text-ellipsis 类名模式
        // 匹配 getEllipsisClass() 等函数调用
        if (cleanExpression.includes('getEllipsisClass')) {
            // 检查 TextEllipsisDemo.uvue 中 getEllipsisClass 函数的实现
            // 它返回 `text-ellipsis-${lines}` 格式，所以我们预生成 1-10
            for (let i = 1; i <= 10; i++) {
                classNames.add(`text-ellipsis-${i}`);
            }
            if (isDev) console.log(`[JZ UnoCSS] 从 getEllipsisClass 函数调用生成 text-ellipsis-1 到 text-ellipsis-10`);
        }
        
        // 9. 特殊处理：检查是否包含 text-ellipsis 相关的循环变量
        // 匹配 num 变量在 1-10 循环中的使用
        if (cleanExpression.includes('text-ellipsis-') && (cleanExpression.includes('${num}') || cleanExpression.includes('num'))) {
            // 为循环变量生成 1-10 的所有可能值
            for (let i = 1; i <= 10; i++) {
                classNames.add(`text-ellipsis-${i}`);
            }
            if (isDev) console.log(`[JZ UnoCSS] 从循环变量 num 生成 text-ellipsis-1 到 text-ellipsis-10`);
        }
        
        const result = Array.from(classNames);
        
        // 只在有结果或开发模式时输出日志
        if (result.length > 0 || isDev) {
            console.log(`[JZ UnoCSS] 动态表达式 "${cleanExpression}" 提取到类名:`, result);
        }
        
        return result;
        
    } catch (error) {
        // 静默处理解析错误，避免影响主流程
        console.warn('[JZ UnoCSS] 动态类名解析警告:', error.message);
        return [];
    }
}

/**
 * 从代码中提取类名和组合信息
 * @param {string} code - 源代码
 * @returns {Object} 包含类名数组和组合信息的对象
 */
export function extractClassNamesWithContext(code) {
    // 输入参数检查
    if (!code || typeof code !== 'string') {
        console.warn('[JZ UnoCSS] extractClassNamesWithContext: 无效的代码输入');
        return {
            allClassNames: [],
            classNameGroups: []
        };
    }
    
    const allClassNames = [];
    const classNameGroups = [];
    
    try {
        // 1. 处理静态 class="..." 中的类名
        const staticClassRegex = /\bclass\s*=\s*["']([^"']+)["']/g;
        let match;
        
        while ((match = staticClassRegex.exec(code)) !== null) {
            const classString = match[1];
            // 分割多个类名（用空格分隔）
            const classes = classString.split(/\s+/).filter(cls => cls.trim());
            
            if (classes.length > 0) {
                // 添加到总类名列表
                classes.forEach(cls => {
                    if (cls.trim()) {
                        allClassNames.push(cls.trim());
                    }
                });
                
                // 如果有多个类名，添加到组合中
                if (classes.length > 1) {
                    classNameGroups.push(classes.map(cls => cls.trim()));
                }
            }
        }
        
        // 2. 智能处理动态 :class="..." 中的类名
        // 使用更强的正则匹配，支持嵌套引号的复杂表达式
        const dynamicClassRegex = /:class\s*=\s*"([^"]+)"/g;
        const dynamicClassRegexSingle = /:class\s*=\s*'([^']+)'/g;
        
        // 处理双引号包裹的表达式
        while ((match = dynamicClassRegex.exec(code)) !== null) {
            const expression = match[1];
            
            // 跳过空表达式
            if (!expression || !expression.trim()) {
                continue;
            }
            
            console.log(`[JZ UnoCSS] 处理动态类名表达式（双引号）: ${expression}`);
            
            // 使用安全的提取方法
            const dynamicClassNames = extractClassNamesFromDynamicExpression(expression);
            
            if (dynamicClassNames.length > 0) {
                console.log(`[JZ UnoCSS] 从动态表达式提取到类名:`, dynamicClassNames);
                
                // 添加到总类名列表
                dynamicClassNames.forEach(cls => {
                    allClassNames.push(cls);
                });
                
                // 如果有多个类名，添加到组合中
                if (dynamicClassNames.length > 1) {
                    classNameGroups.push(dynamicClassNames);
                }
            }
        }
        
        // 处理单引号包裹的表达式
        while ((match = dynamicClassRegexSingle.exec(code)) !== null) {
            const expression = match[1];
            
            // 跳过空表达式
            if (!expression || !expression.trim()) {
                continue;
            }
            
            console.log(`[JZ UnoCSS] 处理动态类名表达式（单引号）: ${expression}`);
            
            // 使用安全的提取方法
            const dynamicClassNames = extractClassNamesFromDynamicExpression(expression);
            
            if (dynamicClassNames.length > 0) {
                console.log(`[JZ UnoCSS] 从动态表达式提取到类名:`, dynamicClassNames);
                
                // 添加到总类名列表
                dynamicClassNames.forEach(cls => {
                    allClassNames.push(cls);
                });
                
                // 如果有多个类名，添加到组合中
                if (dynamicClassNames.length > 1) {
                    classNameGroups.push(dynamicClassNames);
                }
            }
        }
        
        // 3. 处理 class 和 :class 混合使用的情况
        // 这种情况在实际使用中很常见：<div class="static-class" :class="dynamic-class">
        const mixedClassRegex = /\bclass\s*=\s*(['"'])([^'"]+)\1[^>]*:class\s*=\s*(['"'])([^'"]*?)\3/g;
        while ((match = mixedClassRegex.exec(code)) !== null) {
            const staticClasses = match[2].split(/\s+/).filter(cls => cls.trim());
            const dynamicExpression = match[4];
            const dynamicClasses = extractClassNamesFromDynamicExpression(dynamicExpression);
            
            // 合并静态和动态类名作为组合
            const combinedClasses = [...staticClasses, ...dynamicClasses];
            if (combinedClasses.length > 1) {
                classNameGroups.push(combinedClasses);
            }
        }
        
        // 4. 处理反向混合使用：:class 在前，class 在后
        const reverseMixedClassRegex = /:class\s*=\s*(['"'])([^'"]*?)\1[^>]*\bclass\s*=\s*(['"'])([^'"]+)\3/g;
        while ((match = reverseMixedClassRegex.exec(code)) !== null) {
            const dynamicExpression = match[2];
            const staticClasses = match[4].split(/\s+/).filter(cls => cls.trim());
            const dynamicClasses = extractClassNamesFromDynamicExpression(dynamicExpression);
            
            // 合并静态和动态类名作为组合
            const combinedClasses = [...dynamicClasses, ...staticClasses];
            if (combinedClasses.length > 1) {
                classNameGroups.push(combinedClasses);
            }
        }
        
        // 5. 直接匹配代码中的模板字符串 text-ellipsis 模式
        // 匹配 `text-ellipsis-${variable}` 模式，即使不在 :class 属性中
        const templateStringRegex = /`([^`]*text-ellipsis-\$\{[^}]+\}[^`]*)`/g;
        while ((match = templateStringRegex.exec(code)) !== null) {
            const templateContent = match[1];
            console.log(`[JZ UnoCSS] 发现模板字符串: ${match[0]}`);
            
            // 检查是否是 text-ellipsis 模式
            if (templateContent.includes('text-ellipsis-${')) {
                // 为 1-10 生成所有可能的 text-ellipsis 类名
                for (let i = 1; i <= 10; i++) {
                    allClassNames.push(`text-ellipsis-${i}`);
                }
                console.log(`[JZ UnoCSS] 从模板字符串生成 text-ellipsis-1 到 text-ellipsis-10`);
            }
        }
        
        // 6. 检查函数定义中的 text-ellipsis 返回值
        // 匹配 getEllipsisClass 等函数，如果函数内部返回 text-ellipsis 模式
        const functionDefRegex = /function\s+(\w*[Ee]llipsis\w*)\s*\([^)]*\)[^}]*\{[^}]*text-ellipsis[^}]*\}/g;
        while ((match = functionDefRegex.exec(code)) !== null) {
            console.log(`[JZ UnoCSS] 发现与 ellipsis 相关的函数: ${match[1]}`);
            // 为 1-10 生成所有可能的 text-ellipsis 类名
            for (let i = 1; i <= 10; i++) {
                allClassNames.push(`text-ellipsis-${i}`);
            }
            console.log(`[JZ UnoCSS] 从函数 ${match[1]} 生成 text-ellipsis-1 到 text-ellipsis-10`);
        }
        
        // 7. 检查循环中使用的 text-ellipsis 模式
        // 匹配 v-for="num in 10" 配合 text-ellipsis-${num} 的模式
        if (code.includes('text-ellipsis-') && (code.includes('v-for') || code.includes('for ('))) {
            console.log(`[JZ UnoCSS] 发现循环中的 text-ellipsis 使用`);
            // 为 1-10 生成所有可能的 text-ellipsis 类名
            for (let i = 1; i <= 10; i++) {
                allClassNames.push(`text-ellipsis-${i}`);
            }
            console.log(`[JZ UnoCSS] 从循环模式生成 text-ellipsis-1 到 text-ellipsis-10`);
        }
        
        console.log(`[JZ UnoCSS] 总共提取到 ${allClassNames.length} 个类名，${classNameGroups.length} 个类名组合`);
        
    } catch (error) {
        console.error('[JZ UnoCSS] extractClassNamesWithContext 处理过程出错:', error.message);
    }
    
    return {
        allClassNames,
        classNameGroups
    };
}

/**
 * 从代码中提取类名
 * @param {string} code - 源代码
 * @returns {string[]} 类名数组
 */
export function extractClassNamesFromCode(code) {
    const result = extractClassNamesWithContext(code);
    return result.allClassNames || [];
}

/**
 * 生成CSS并写入文件
 * @param {string[]} classNames - 类名数组
 * @param {Object} options - 选项
 * @returns {string[]} 生成的CSS规则数组
 */
export function generateAndWriteCSS(classNames, options = {}) {
    const cssRules = [];
    const processedClasses = new Set();
    
    // 去重
    const uniqueClassNames = [...new Set(classNames)];
    
    for (const className of uniqueClassNames) {
        if (processedClasses.has(className)) {
            continue;
        }
        
        try {
            const styles = generateCSS(className, options);
            if (styles && typeof styles === 'object' && Object.keys(styles).length > 0) {
                // 生成CSS规则
                const selector = utils.encodeClassNameForUvue(className);
                const cssProps = Object.entries(styles)
                    .filter(([prop]) => !prop.startsWith('__'))
                    .map(([prop, value]) => `  ${prop}: ${value};`)
                    .join('\n');
                
                const cssRule = `.${selector} {\n${cssProps}\n}`;
                cssRules.push(cssRule);
            } else if (typeof styles === 'string') {
                // 直接是CSS字符串（如条件编译CSS）
                cssRules.push(styles);
            }
            
            processedClasses.add(className);
        } catch (error) {
            console.warn(`[JZ UnoCSS] 生成CSS失败 ${className}:`, error.message);
        }
    }
    
    return cssRules;
}

/**
 * 更新主CSS文件
 * @param {string} cssContent - CSS内容
 * @param {Object} config - 配置对象
 * @returns {boolean} 是否成功写入
 */
export function updateMainCSS(cssContent, config = {}) {
    const outputPath = config.cssOutputPath || 'uni_modules/jz-unocss-uvue/main.css';
    
    try {
        // 尝试使用Node.js fs模块
        const fs = require('fs');
        const path = require('path');
        
        // 确保目录存在
        const dir = path.dirname(outputPath);
        if (!fs.existsSync(dir)) {
            fs.mkdirSync(dir, { recursive: true });
        }
        
        // 写入文件
        fs.writeFileSync(outputPath, cssContent, 'utf-8');
        return true;
    } catch (error) {
        console.warn('[JZ UnoCSS] 写入 main.css 时出错:', error.message);
        return false;
    }
}

/**
 * 生成最小化CSS
 * @param {string[]} classNames - 类名数组
 * @param {Object} options - 选项
 * @returns {string} CSS字符串
 */
export function generateMinimalCSS(classNames, options = {}) {
    const cssRules = generateAndWriteCSS(classNames, { ...options, mode: 'production' });
    // 确保cssRules是数组
    return Array.isArray(cssRules) ? cssRules.join('') : '';
}

/**
 * 生成基础CSS
 * @param {string[]} classNames - 类名数组
 * @param {Object} options - 选项
 * @returns {string} CSS字符串
 */
export function generateBasicCSS(classNames, options = {}) {
    const cssRules = generateAndWriteCSS(classNames, { ...options, mode: 'development' });
    // 确保cssRules是数组
    return Array.isArray(cssRules) ? cssRules.join('\n\n') + '\n' : '';
}

/**
 * 生成备用CSS（兼容性处理）
 * @param {string[]} classNames - 类名数组
 * @param {Object} options - 选项
 * @returns {string} CSS字符串
 */
export function generateFallbackCSS(classNames, options = {}) {
    const cssRules = [];
    
    for (const className of classNames) {
        try {
            const styles = generateCSS(className, options);
            if (styles && typeof styles === 'object' && Object.keys(styles).length > 0) {
                const selector = className.replace(/[/\[\]#(),%.:]/g, '\\$&');
                const cssProps = Object.entries(styles)
                    .filter(([prop]) => !prop.startsWith('__'))
                    .map(([prop, value]) => `${prop}:${value}`)
                    .join(';');
                cssRules.push(`.${selector}{${cssProps}}`);
            }
        } catch (error) {
            // 静默处理错误
        }
    }
    
    return cssRules.join('');
}

/**
 * 写入CSS文件的通用函数
 * @param {string} outputPath - 输出路径
 * @param {string} cssContent - CSS内容
 * @returns {boolean} 是否成功写入
 */
export function updateCSSFile(outputPath, cssContent) {
    try {
        // 尝试使用Node.js fs模块
        const fs = require('fs');
        const path = require('path');
        
        // 确保目录存在
        const dir = path.dirname(outputPath);
        if (!fs.existsSync(dir)) {
            fs.mkdirSync(dir, { recursive: true });
        }
        
        // 写入文件
        fs.writeFileSync(outputPath, cssContent, 'utf-8');
        return true;
    } catch (error) {
        console.warn('[JZ UnoCSS] 写入CSS文件时出错:', error.message);
        return false;
    }
}

/**
 * 添加CSS规则到现有文件
 * @param {string[]} newCSSRules - 新的CSS规则数组
 * @param {Object} config - 配置对象
 * @returns {boolean} 是否成功添加
 */
export function addCSSRulesToFile(newCSSRules, config = {}) {
    // 确保newCSSRules是数组
    if (!Array.isArray(newCSSRules) || newCSSRules.length === 0) {
        return false;
    }
    
    const outputPath = config.cssOutputPath || 'uni_modules/jz-unocss-uvue/main.css';
    
    try {
        const fs = require('fs');
        const path = require('path');
        
        // 读取现有内容
        let existingContent = '';
        if (fs.existsSync(outputPath)) {
            existingContent = fs.readFileSync(outputPath, 'utf-8');
        }
        
        // 提取现有的CSS规则选择器
        const existingSelectors = new Set();
        const cssRuleRegex = /\.[\w\-\\[\]]+\s*\{/g;
        let match;
        while ((match = cssRuleRegex.exec(existingContent)) !== null) {
            const selector = match[0].replace(/\s*\{$/, '').trim();
            existingSelectors.add(selector);
        }
        
        // 过滤掉已存在的规则
        const actuallyNewRules = newCSSRules.filter(rule => {
            const selectorMatch = rule.match(/^\.[\w\-\\[\]]+/);
            if (selectorMatch) {
                const selector = selectorMatch[0];
                return !existingSelectors.has(selector);
            }
            return true;
        });
        
        if (actuallyNewRules.length === 0) {
            return false;
        }
        
        // 添加新规则
        const newContent = actuallyNewRules.join('\n\n');
        const finalContent = existingContent 
            ? existingContent + '\n\n' + newContent 
            : newContent;
        
        // 确保目录存在
        const dir = path.dirname(outputPath);
        if (!fs.existsSync(dir)) {
            fs.mkdirSync(dir, { recursive: true });
        }
        
        // 写入文件
        fs.writeFileSync(outputPath, finalContent, 'utf-8');
        
        return true;
    } catch (error) {
        console.error('[JZ UnoCSS] ❌ 写入样式文件失败:', error.message);
        return false;
    }
}

// 函数已在定义时导出，无需重复导出 